import os
import re
from datetime import datetime

def clear_screen():
    """清屏，兼容Linux"""
    os.system('clear')

def log_analyzer():
    """日志分析主函数"""
    log_entries = []
    filtered_entries = []
    current_page = 0
    max_page_size = 50
    search_text = ""
    level_filter = "全部级别"

    def load_logs():
        """加载Linux系统日志"""
        nonlocal log_entries
        log_entries = []
        log_files = ["/var/log/syslog", "/var/log/messages"]
        log_file = None

        for file in log_files:
            if os.path.exists(file):
                log_file = file
                break

        if not log_file:
            print("未找到系统日志文件（/var/log/syslog 或 /var/log/messages）")
            return

        try:
            with open(log_file, 'r', encoding='utf-8', errors='replace') as f:
                for line in f:
                    entry = parse_log_line(line)
                    if entry:
                        log_entries.append(entry)
            log_entries.sort(key=lambda x: x['raw_time'], reverse=True)
            log_entries[:] = log_entries[:1000]  # 限制最大1000条
        except Exception as e:
            print(f"加载日志失败: {e}")

    def parse_log_line(line):
        """解析单行日志"""
        # 典型Linux日志格式: "Mon DD HH:MM:SS hostname process[pid]: message"
        pattern = r'^(\w+\s+\d+\s+\d+:\d+:\d+)\s+([\w-]+)\s+([^\[]+)\[(\d+)\]:\s+(.+)$'
        match = re.match(pattern, line)
        if not match:
            return None

        timestamp_str, hostname, process, pid, message = match.groups()
        try:
            # 假设年份为当前年份
            current_year = datetime.now().year
            timestamp = datetime.strptime(f"{current_year} {timestamp_str}", "%Y %b %d %H:%M:%S")
            level = determine_log_level(message)
            source = f"{process}[{pid}]"
            return {
                'timestamp': timestamp.strftime("%Y-%m-%d %H:%M:%S"),
                'raw_time': timestamp,
                'level': level,
                'source': source,
                'message': message.strip(),
                'full_message': message.strip()
            }
        except ValueError:
            return None

    def determine_log_level(message):
        """根据消息内容判断日志级别"""
        message_lower = message.lower()
        if "error" in message_lower or "failed" in message_lower or "exception" in message_lower:
            return "ERROR"
        elif "warn" in message_lower or "warning" in message_lower:
            return "WARNING"
        return "INFO"

    def filter_logs():
        """应用过滤条件"""
        nonlocal filtered_entries
        filtered_entries = []

        for entry in log_entries:
            if search_text:
                if (search_text.lower() not in entry['message'].lower() and
                        search_text.lower() not in entry['source'].lower()):
                    continue
            if level_filter != "全部级别" and entry['level'] != level_filter:
                continue
            filtered_entries.append(entry)

    def display_logs():
        """显示日志列表"""
        clear_screen()
        print("=" * 80)
        print("系统日志分析")
        print("=" * 80)
        stats = get_log_statistics()
        print(f"总日志数: {len(log_entries)} | 错误: {stats['levels'].get('ERROR', 0)} | 警告: {stats['levels'].get('WARNING', 0)}")
        print(f"当前过滤: 级别={level_filter} | 搜索={search_text or '无'}")
        print("-" * 80)

        total_pages = max(1, (len(filtered_entries) + max_page_size - 1) // max_page_size)
        start_idx = current_page * max_page_size
        end_idx = min(start_idx + max_page_size, len(filtered_entries))
        displayed = filtered_entries[start_idx:end_idx]

        print(f"{'Time':<20} {'Level':<10} {'Source':<20} {'Message':<50}")
        print("-" * 80)
        for entry in displayed:
            message = (entry['message'][:100] + "...") if len(entry['message']) > 30 else entry['message']
            print(f"{entry['timestamp']:<20} {entry['level']:<10} {entry['source'][:18]:<20} {message}")
        print("-" * 80)
        print(f"第 {current_page + 1} 页 / 共 {total_pages} 页")
        print("\n操作: [r] 刷新 | [s] 搜索 | [f] 过滤 | [e] 导出报告 | [p] 上一页 | [n] 下一页 | [q] 返回")

    def get_log_statistics():
        """获取统计信息"""
        stats = {
            'levels': {},
            'sources': {},
            'error_sources': {}
        }
        for entry in log_entries:
            level = entry['level']
            stats['levels'][level] = stats['levels'].get(level, 0) + 1
            source = entry['source']
            stats['sources'][source] = stats['sources'].get(source, 0) + 1
            if level == "ERROR":
                stats['error_sources'][source] = stats['error_sources'].get(source, 0) + 1
        stats['error_sources'] = dict(sorted(stats['error_sources'].items(), key=lambda x: x[1], reverse=True))
        return stats

    def export_report():
        """导出报告"""
        try:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"security_log_report_{timestamp}.txt"
            stats = get_log_statistics()

            with open(filename, 'w', encoding='utf-8') as f:
                f.write("=" * 80 + "\n")
                f.write("Linux 系统日志分析报告\n")
                f.write("=" * 60 + "\n")
                f.write(f"报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"操作系统: Linux\n")
                f.write(f"总记录数: {len(log_entries)}\n")
                f.write(f"当前显示: {len(filtered_entries)}\n\n")
                f.write("日志级别统计:\n")
                f.write("-" * 30 + "\n")
                for level, count in stats['levels'].items():
                    f.write(f"{level:12}: {count:6} 条\n")
                f.write("\n")
                f.write("日志来源统计:\n")
                f.write("-" * 30 + "\n")
                for source, count in sorted(stats['sources'].items(), key=lambda x: x[1], reverse=True)[:10]:
                    f.write(f"{source:20}: {count:6} 条\n")
                f.write("\n")
                if stats['error_sources']:
                    f.write("错误来源统计 (前5):\n")
                    f.write("-" * 30 + "\n")
                    for source, count in list(stats['error_sources'].items())[:5]:
                        f.write(f"  {source}: {count} 个错误\n")
                    f.write("\n")
                    f.write("详细日志列表:\n")
                    f.write("=" * 60 + "\n")
                    for entry in filtered_entries:
                        f.write(f"时间: {entry['timestamp']}\n")
                        f.write(f"级别: {entry['level']}\n")
                        f.write(f"来源: {entry['source']}\n")
                        f.write(f"消息: {entry['full_message']}\n")
                        f.write("-" * 60 + "\n")

            print(f"\n报告已保存为 {filename}")
        except Exception as e:
            print(f"\n导出报告失败: {e}")
        input("\n按 Enter 继续...")

    while True:
        load_logs()
        filter_logs()
        display_logs()

        choice = input("请输入操作: ").lower()
        if choice == 'q':
            break
        elif choice == 'r':
            continue
        elif choice == 's':
            search_text = input("请输入搜索关键词（消息或来源）: ")
            current_page = 0
        elif choice == 'f':
            print("\n过滤选项: [1] 全部级别 | [2] INFO | [3] WARNING | [4] ERROR")
            filter_choice = input("请选择级别 (1-4): ")
            filter_map = {"1": "全部级别", "2": "INFO", "3": "WARNING", "4": "ERROR"}
            level_filter = filter_map.get(filter_choice, "全部级别")
            current_page = 0
        elif choice == 'e':
            export_report()
        elif choice == 'p':
            if current_page > 0:
                current_page -= 1
        elif choice == 'n':
            total_pages = max(1, (len(filtered_entries) + max_page_size - 1) // max_page_size)
            if current_page < total_pages - 1:
                current_page += 1
        else:
            print("无效操作，请重试")
            input("\n按 Enter 继续...")